#include "Layout.h"

#include <algorithm>

#include "../_Luly.h"

Layout::Layout(std::string uiObjectId, Layout::Arrangement arrangement,
               Layout::Alignment alignment, int x, int y)
    : UIObject(uiObjectId, x, y),
      arrangement(arrangement),
      alignment(alignment) {}

void Layout::init() { UIObject::init(); }

void Layout::draw() {
  // int w = 0, h = 0;  //宽高的中间变量

  // if (arrangement == Layout::Arrangement::HORIZONTAL ||
  //     arrangement == Layout::Arrangement::RE_HORIZONTAL) {
  //   for (int i = 0; i < child_objects.getSize(); i++) {
  //     //更新wh大小
  //     w += child_objects[i].second->getWidth();
  //     if (child_objects[i].second->getHeight() > h) {
  //       h = child_objects[i].second->getHeight();
  //     }
  //   }
  // } else if (arrangement == Layout::Arrangement::VERTICAL ||
  //            arrangement == Layout::Arrangement::RE_VERTICAL) {
  //   for (int i = 0; i < child_objects.getSize(); i++) {
  //     //更新wh大小
  //     h += child_objects[i].second->getHeight();
  //     if (child_objects[i].second->getWidth() > w) {
  //       w = child_objects[i].second->getWidth();
  //     }
  //   }
  // }

  // int dx = 0;
  // int dy = 0;
  // switch (alignment) {
  //   case Alignment::LEFT_TOP: {
  //     dx = 0;
  //     dy = 0;
  //     break;
  //   }
  //   case Alignment::CENTER_TOP: {
  //     dx = (width - w) / 2;
  //     dy = 0;
  //     break;
  //   }
  //   case Alignment::RIGHT_TOP: {
  //     dx = width - w;
  //     dy = 0;
  //     break;
  //   }
  //   case Alignment::CENTER_LEFT: {
  //     dx = 0;
  //     dy = (height - h) / 2;
  //     break;
  //   }
  //   case Alignment::CENTER: {
  //     dx = (width - w) / 2;
  //     dy = (height - h) / 2;
  //     break;
  //   }
  //   case Alignment::CENTER_RIGHT: {
  //     dx = width - w;
  //     dy = (height - h) / 2;
  //     break;
  //   }
  //   case Alignment::LEFT_BOTTOM: {
  //     dx = 0;
  //     dy = height - h;
  //     break;
  //   }
  //   case Alignment::CENTER_BOTTOM: {
  //     dx = (width - w) / 2;
  //     dy = height - h;
  //     break;
  //   }
  //   case Alignment::RIGHT_BOTTOM: {
  //     dx = width - w;
  //     dy = height - h;
  //     break;
  //   }
  // }

  // //动态调整子对象的位置
  // switch (arrangement) {
  //   case Layout::Arrangement::NORMAL:
  //     break;
  //   case Layout::Arrangement::HORIZONTAL: {
  //     for (int i = 0; i < child_objects.getSize(); i++) {
  //       child_objects[i].second->setX(x + dx);
  //       child_objects[i].second->setY(y + dy);
  //       dx += (child_objects[i].second->getWidth());
  //     }
  //     break;
  //   }

  //   case Layout::Arrangement::RE_HORIZONTAL: {
  //     for (int i = child_objects.getSize() - 1; i >= 0; i--) {
  //       child_objects[i].second->setX(x + dx);
  //       child_objects[i].second->setY(y + dy);
  //       dx += (child_objects[i].second->getWidth());
  //     }

  //     break;
  //   }

  //   case Layout::Arrangement::VERTICAL: {
  //     for (int i = 0; i < child_objects.getSize(); i++) {
  //       child_objects[i].second->setX(x + dx);
  //       child_objects[i].second->setY(y + dy);
  //       dy += (child_objects[i].second->getHeight());
  //     }
  //     break;
  //   }

  //   case Layout::Arrangement::RE_VERTICAL: {
  //     for (int i = child_objects.getSize() - 1; i >= 0; i--) {
  //       child_objects[i].second->setX(x + dx);
  //       child_objects[i].second->setY(y + dy);
  //       dy += (child_objects[i].second->getHeight());
  //     }
  //     break;
  //   }

  //   default:
  //     break;
  // }

  // //处理子对象的宽高
  // int h_fill_num = 0;
  // int h_fit = 0;
  // int w_fill_num = 0;
  // int w_fit = 0;

  // float h_weight_sum = 0;
  // float w_weight_sum = 0;
  // //获得x_fill_num, x_fit
  // for (int i = 0; i < child_objects.getSize(); i++) {
  //   switch (child_objects[i].second->getHeightMode()) {
  //     case WHMode::FILL:
  //       h_fill_num++;
  //       h_weight_sum += child_objects[i].second->getHeightWeight();
  //       break;
  //     case WHMode::FIT:
  //       h_fit += child_objects[i].second->getHeight();
  //       break;
  //     default:
  //       break;
  //   }
  //   switch (child_objects[i].second->getWidthMode()) {
  //     case WHMode::FILL:
  //       w_fill_num++;
  //       w_weight_sum += child_objects[i].second->getWidthWeight();
  //       break;
  //     case WHMode::FIT:
  //       w_fit += child_objects[i].second->getWidth();
  //       break;
  //     default:
  //       break;
  //   }
  // }

  // //如果没有父对象（即为根布局）
  // if (parent_object == nullptr) {
  //   if (widthMode == WHMode::FIT) {
  //     //没有fill就说明就是fit
  //     if (w_fill_num == 0) {
  //       width = w;
  //     } else {
  //       width = _Luly::getInstance().windowWidth;
  //     }
  //   } else if (widthMode == WHMode::FILL) {
  //     width = _Luly::getInstance().windowWidth;
  //   }
  //   if (heightMode == WHMode::FIT) {
  //     if (h_fill_num == 0) {
  //       height = h;
  //     }
  //     // else {
  //     //   //如果子对象中有一个是FILL，那么，该对象也会FILL
  //     //   // height = _Luly::getInstance().windowHeight;
  //     // }
  //   } else if (heightMode == WHMode::FILL) {
  //     height = _Luly::getInstance().windowHeight;
  //   }
  // } else {
  //   if (widthMode == WHMode::FIT) {
  //     width = w;
  //   }
  //   if (heightMode == WHMode::FIT) {
  //     height = h;
  //   }
  // }

  // //不管是不是根布局，都要对子对象宽高进行调整

  // for (int i = 0; i < child_objects.getSize(); i++) {
  //   switch (child_objects[i].second->getWidthMode()) {
  //     case WHMode::FILL:
  //       if ((arrangement == Arrangement::HORIZONTAL ||
  //            arrangement == Arrangement::RE_HORIZONTAL)) {
  //         child_objects[i].second->setWidth(
  //             int((width - w_fit) *
  //                 (child_objects[i].second->getWidthWeight() /
  //                 w_weight_sum)));

  //       } else {
  //         child_objects[i].second->setWidth(width );
  //       }
  //       break;
  //     default:
  //       break;
  //   }
  //   switch (child_objects[i].second->getHeightMode()) {
  //     case WHMode::FILL:
  //       if (arrangement == Arrangement::VERTICAL ||
  //           arrangement == Arrangement::RE_VERTICAL) {
  //         child_objects[i].second->setHeight(
  //             int((height - h_fit) *
  //                 (child_objects[i].second->getHeightWeight() /
  //                 h_weight_sum)));

  //       } else {
  //         child_objects[i].second->setHeight(height );
  //       }

  //       break;
  //     default:
  //       break;
  //   }
  // }

  // UIObject::draw();
  drawArea(Rect{contentX, contentY, contentWidth, contentHeight});
}

void Layout::drawArea(const Rect& area) {
  int w = 0, h = 0;  //宽高的中间变量

  if (arrangement == Layout::Arrangement::HORIZONTAL ||
      arrangement == Layout::Arrangement::RE_HORIZONTAL) {
    for (int i = 0; i < child_objects.getSize(); i++) {
      //更新wh大小
      w += child_objects[i].second->getWidth();
      if (child_objects[i].second->getHeight() > h) {
        h = child_objects[i].second->getHeight();
      }
    }
  } else if (arrangement == Layout::Arrangement::VERTICAL ||
             arrangement == Layout::Arrangement::RE_VERTICAL) {
    for (int i = 0; i < child_objects.getSize(); i++) {
      //更新wh大小
      h += child_objects[i].second->getHeight();
      if (child_objects[i].second->getWidth() > w) {
        w = child_objects[i].second->getWidth();
      }
    }
  }

  int dx = 0;
  int dy = 0;
  switch (alignment) {
    case Alignment::LEFT_TOP: {
      dx = 0;
      dy = 0;
      break;
    }
    case Alignment::CENTER_TOP: {
      dx = (width - w) / 2;
      dy = 0;
      break;
    }
    case Alignment::RIGHT_TOP: {
      dx = width - w;
      dy = 0;
      break;
    }
    case Alignment::CENTER_LEFT: {
      dx = 0;
      dy = (height - h) / 2;
      break;
    }
    case Alignment::CENTER: {
      dx = (width - w) / 2;
      dy = (height - h) / 2;
      break;
    }
    case Alignment::CENTER_RIGHT: {
      dx = width - w;
      dy = (height - h) / 2;
      break;
    }
    case Alignment::LEFT_BOTTOM: {
      dx = 0;
      dy = height - h;
      break;
    }
    case Alignment::CENTER_BOTTOM: {
      dx = (width - w) / 2;
      dy = height - h;
      break;
    }
    case Alignment::RIGHT_BOTTOM: {
      dx = width - w;
      dy = height - h;
      break;
    }
  }

  //动态调整子对象的位置
  switch (arrangement) {
    case Layout::Arrangement::NORMAL:
      break;
    case Layout::Arrangement::HORIZONTAL: {
      for (int i = 0; i < child_objects.getSize(); i++) {
        child_objects[i].second->setX(x + dx);
        child_objects[i].second->setY(y + dy);
        dx += (child_objects[i].second->getWidth());
      }
      break;
    }

    case Layout::Arrangement::RE_HORIZONTAL: {
      for (int i = child_objects.getSize() - 1; i >= 0; i--) {
        child_objects[i].second->setX(x + dx);
        child_objects[i].second->setY(y + dy);
        dx += (child_objects[i].second->getWidth());
      }

      break;
    }

    case Layout::Arrangement::VERTICAL: {
      for (int i = 0; i < child_objects.getSize(); i++) {
        child_objects[i].second->setX(x + dx);
        child_objects[i].second->setY(y + dy);
        dy += (child_objects[i].second->getHeight());
      }
      break;
    }

    case Layout::Arrangement::RE_VERTICAL: {
      for (int i = child_objects.getSize() - 1; i >= 0; i--) {
        child_objects[i].second->setX(x + dx);
        child_objects[i].second->setY(y + dy);
        dy += (child_objects[i].second->getHeight());
      }
      break;
    }

    default:
      break;
  }

  //处理子对象的宽高
  int h_fill_num = 0;
  int h_fit = 0;
  int w_fill_num = 0;
  int w_fit = 0;

  float h_weight_sum = 0;
  float w_weight_sum = 0;
  //获得x_fill_num, x_fit
  for (int i = 0; i < child_objects.getSize(); i++) {
    switch (child_objects[i].second->getHeightMode()) {
      case WHMode::FILL:
        h_fill_num++;
        h_weight_sum += child_objects[i].second->getHeightWeight();
        break;
      case WHMode::FIT:
        h_fit += child_objects[i].second->getHeight();
        break;
      default:
        break;
    }
    switch (child_objects[i].second->getWidthMode()) {
      case WHMode::FILL:
        w_fill_num++;
        w_weight_sum += child_objects[i].second->getWidthWeight();
        break;
      case WHMode::FIT:
        w_fit += child_objects[i].second->getWidth();
        break;
      default:
        break;
    }
  }

  //如果没有父对象（即为根布局）
  if (parent_object == nullptr) {
    if (widthMode == WHMode::FIT) {
      //没有fill就说明就是fit
      if (w_fill_num == 0) {
        width = w;
      } else {
        width = _Luly::getInstance().windowWidth;
      }
    } else if (widthMode == WHMode::FILL) {
      width = _Luly::getInstance().windowWidth;
    }
    if (heightMode == WHMode::FIT) {
      if (h_fill_num == 0) {
        height = h;
      }
      // else {
      //   //如果子对象中有一个是FILL，那么，该对象也会FILL
      //   // height = _Luly::getInstance().windowHeight;
      // }
    } else if (heightMode == WHMode::FILL) {
      height = _Luly::getInstance().windowHeight;
    }
  } else {
    if (widthMode == WHMode::FIT) {
      width = w;
    }
    if (heightMode == WHMode::FIT) {
      height = h;
    }
  }

  //不管是不是根布局，都要对子对象宽高进行调整

  for (int i = 0; i < child_objects.getSize(); i++) {
    switch (child_objects[i].second->getWidthMode()) {
      case WHMode::FILL:
        if ((arrangement == Arrangement::HORIZONTAL ||
             arrangement == Arrangement::RE_HORIZONTAL)) {
          child_objects[i].second->setWidth(
              int((width - w_fit) *
                  (child_objects[i].second->getWidthWeight() / w_weight_sum)));

        } else {
          child_objects[i].second->setWidth(width);
        }
        break;
      default:
        break;
    }
    switch (child_objects[i].second->getHeightMode()) {
      case WHMode::FILL:
        if (arrangement == Arrangement::VERTICAL ||
            arrangement == Arrangement::RE_VERTICAL) {
          child_objects[i].second->setHeight(
              int((height - h_fit) *
                  (child_objects[i].second->getHeightWeight() / h_weight_sum)));

        } else {
          child_objects[i].second->setHeight(height);
        }

        break;
      default:
        break;
    }
  }
  // printf("%s,w:%d\n",uiObjectId.c_str(),width);
  //   printf("%s,x:%d\n",uiObjectId.c_str(),x);
  UIObject::drawArea(area);
}
